<?php

namespace app\admin\service;

use app\common\Common;
use app\model\VideoDetails;
use think\facade\Cache;
use think\facade\Request;

class DouYinService
{
    public $domain;
    public $douyinConf;

    public function __construct() {
        $this->domain = 'https://open.douyin.com';
        $this->douyinConf = config('tiktok.applet');
    }

    public static $douyinTag = [
        1 =>'医神',
        2 =>'赘婿',
        3 =>'鉴宝',
        4 =>'战神',
        5 =>'娱乐明星',
        6 =>'神医',
        7 =>'重生',
        8 =>'职场',
        9 =>'逆袭',
        10 =>'复仇',
        11 =>'青春',
        12 =>'官场',
        13 =>'家庭情感',
        14 =>'乡村',
        15 =>'正能量',
        16 =>'成长',
        17 =>'伦理',
        18 =>'都市情感',
        19 =>'社会话题',
        20 =>'灵异',
        21 =>'悬疑推理',
        22 =>'虐恋',
        23 =>'甜宠',
        24 =>'高干军婚',
        25 =>'年代',
        26 =>'萌宝',
        27 =>'腹黑',
        28 =>'总裁',
        29 =>'宫斗宅斗',
        30 =>'穿越',
        31 =>'种田经商',
        33 =>'民俗',
        34 =>'古装',
        35 =>'穿越战争',
        36 =>'现代军事',
        37 =>'奇幻',
        38 =>'科幻',
        39 =>'架空玄幻',
        40 =>'热血',
        41 =>'历史',
        42 =>'搞笑',
        43 =>'仙侠',
        44 =>'武侠',
        45 =>'二次元',
        46 =>'其他',
    ];

    //获取公共参数
    public function getCommon()
    {
        $clientToken = Common::getTikTokDeveloperClientToken();
        return [
            'Content-Type:application/json',
            'access-token:' . $clientToken
        ];
    }

    //图片上传
    public function imgUpload($url): string
    {
        if (empty($url)) return '';
        $body = [
            'resource_type' => 2,
            'ma_app_id' => $this->douyinConf['appid'],
            'image_meta' => [
                'url' => $url
            ],
        ];

        $header = self::getCommon();
        $url = $this->domain . '/api/playlet/v2/resource/upload/';
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return '';
        return $data['data']['image_result']['open_pic_id'] ?? '';
    }

    //单视频上传
    public function videoUpload($url, $name): string
    {
        $type = pathinfo($url, PATHINFO_EXTENSION) ?: 'mp4';
        $body = [
            'resource_type' => 1,
            'ma_app_id' => $this->douyinConf['appid'],
            'video_meta' => [
                'url' => $url,
                'title' => $name,
                'format' => $type,
                'use_dy_cloud' => true
            ],
        ];

        $header = self::getCommon();
        $url = $this->domain . '/api/playlet/v2/resource/upload/';
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return '';
        return $data['data']['video_result']['open_video_id'] ?? '';
    }

    //保存短剧
    public function saveShortPlay($title, $seq_num, $cover_url, array $inputs, $conf = [])
    {
        if (empty($inputs['tag_ids']) || empty($inputs['release_year'])) return ['msg' => '参数错误', 'data' => []];

        if ($conf && $conf['qualification'] == 2 && empty($inputs['license_num'])) {
            return ['msg' => '请输入备案号', 'data' => []];
        }

        $inputs['tag_ids'] = explode(',', $inputs['tag_ids']);

        $tags = array_keys(self::$douyinTag);
        $tag_ids = [];
        foreach ($inputs['tag_ids'] as $k => $id) {
            if (!in_array($id, $tags)) ['msg' => '参数错误', 'data' => []];
            $tag_ids[] = (int)$id;
            if ($k >= 2) break;
        }

        $is_upload_img = $inputs['is_upload_img'] == 'false' ? false : true;
        if ($conf && !$is_upload_img) {
            $cover_list = $conf['cover_list'];
        }

        if (empty($cover_list)) {
            $res = $this->imgUpload($cover_url);
            if (!$res) return ['msg' => '封面图同步错误', 'data' => []];
            $cover_list = [$res];
            sleep(1);
        }

        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'album_info' => [
                'title' => $title,
                'seq_num' => $seq_num,
                'cover_list' => $cover_list,
                'year' => $inputs['release_year'] ?? date('Y'),
                'album_status' => 3,
                'recommendation' => !empty($inputs['recommendation']) ? $this->format_str($inputs['recommendation'], 12) : '非常好看的短剧',
                'desp' => !empty($inputs['synopsis']) ? $this->format_str($inputs['synopsis'], 200) : '测试数据',
                'tag_list' => $tag_ids,
                'qualification' => $conf['qualification'] ?? 1,
            ]
        ];

        $header = self::getCommon();
        if (!$conf) {
            $url = $this->domain. '/api/playlet/v2/video/create/';
        } else {
            $body['album_id'] = $conf['album_id'];
            if ($body['album_info']['qualification'] == 2) {
                $body['album_info']['record_info']['license_num'] = $inputs['license_num'];
            }
            $detail = VideoDetails::field('id,sort,platform_config')
                ->where('video_id', $inputs['video_id'])
                ->order('sort', 'asc')->limit(1)
                ->find();

            if (!$detail) return ['msg' => '请先更新或者同步剧集', 'data' => []];

            $detail_conf = $detail->platform_config ?: [];
            $detail_douyin_conf = $detail_conf['douyinyun'] ?? [];
            if (!$detail_douyin_conf || empty($detail_douyin_conf['episode_id'])){
                return ['msg' => '请先更新或者同步剧集', 'data' => []];
            }

            $body['episode_info_list'] = [
                [
                    'title' => $title . '-' . $detail->sort,
                    'seq' => $detail->sort,
                    'cover_list' => $cover_list,
                    'open_video_id' => $detail_douyin_conf['open_video_id']
                ]
            ];
            $url = $this->domain. '/api/playlet/v2/video/edit/';
        }

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '保存短剧错误'. ($data['err_msg'] ?? ''), 'data' => []];

        $body['album_id'] = $data['data']['album_id'];
        unset($body['ma_app_id']);
        unset($body['album_info']['desp']);
        if (isset($body['episode_info_list'])){
            unset($body['episode_info_list']);
        }

        return ['msg' => '', 'data' => $body];
    }

    //批量上传剧集媒资视频
    public function uploadVideos($title, array $videos)
    {
        $videoDetailData = [];
        foreach ($videos as $video) {
            $name = $title . '-' . $video['sort'];
            $platformConf = $video['platform_config'] ?? [];
            $platformConf2 = $platformConf['douyinyun'] ?? [];
            $video_open_id = $platformConf2['open_video_id'] ?? '';
            if (empty($video_open_id)) {
                $res = $this->videoUpload($video['url'], $name);
                if (!$res) continue;
                $video_open_id = $res;
                $platformConf2['open_video_id'] = $video_open_id;
                $platformConf2['upload_status'] = 1;
                $platformConf2['sort'] = $video['sort'];
                if (!isset($platformConf2['episode_id'])) {
                    $platformConf2['episode_id'] = '';
                }
                $platformConf2['binding_status'] = 0;
            }

            $platformConf['douyinyun'] = $platformConf2;
            $videoDetailData[] = [
                'id' => $video['id'],
                'platform_config' => $platformConf
            ];
        }

        $videoDetailData && (new VideoDetails())->saveAll($videoDetailData);

        return $videoDetailData ? true : false;
    }

    //批量绑定剧集媒资视频
    public function saveVideos(array $plays, array $videos, $album_id)
    {
        $data = [];
        $videoDetailData = [];
        $album_info = $plays['platform_config'] ?? [];

        foreach ($videos as $video) {
            $name = $plays['name'] . '-' . $video['sort'];
            $platformConf = $video['platform_config']['douyinyun'] ?? [];
            $video_open_id = $platformConf['open_video_id'] ?? '';
            if (empty($video_open_id)) continue;

            $videoDetailData[$video['sort']] = $platformConf;
            $data[] = [
                'title' => $name,
                'seq' => $video['sort'],
                'cover_list' => $album_info['cover_list'] ?? [],
                'open_video_id' => $video_open_id
            ];
        }

        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'album_id' => $album_id,
            'episode_info_list' => $data,
        ];

        //dd($body);die;

        $header = self::getCommon();
        $url = $this->domain. '/api/playlet/v2/video/edit/';

        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '编辑剧集错误'. ($data['err_msg'] ?? ''), 'data' => []];

        foreach ($data['data']['episode_id_map'] as $grade => $datum) {
            if (isset($videoDetailData[$grade])) {
                $videoDetailData[$grade]['episode_id'] = $datum;
                $videoDetailData[$grade]['binding_status'] = 1;
            }
        }

        $updateDatas = [];
        foreach ($videos as $item) {
            $platform_config = $item['platform_config'];
            if (isset($videoDetailData[$item['sort']])) {
                $platform_config['douyinyun'] = $videoDetailData[$item['sort']];
                $updateDatas[] = [
                    'id' => $item['id'],
                    'platform_config' => $platform_config
                ];
            }
        }

        $updateDatas && (new VideoDetails())->saveAll($updateDatas);

        return ['msg' => '', 'data' => ['version' => $data['data']['version']]];
    }

    //送审
    public function audit($album_id)
    {
        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'album_id' => $album_id
        ];

        $url = $this->domain . '/api/playlet/v2/video/review/';
        $header = self::getCommon();

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '送审错误：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => ['log_id' => $data['log_id']]];
    }

    //回调配置
    public function callbackConfig()
    {
        $body = [
            'operator' => 'liuliu',
            'release_reason' => '配置回调地址',
            'industry_impl_list' => [
                [
                    'template_id' => 20001,
                    'open_ability_impl_list' => [
                        [
                            'ability_identity' => '/msg/playlet/review/notify',
                            'is_delete' => false,
                            'test_url' => 'https://ht.sybyn.top/admin/mediaAssets/dyCallback',
                            'prod_url' => 'https://ht.sybyn.top/admin/mediaAssets/dyCallback',
                            'ability_type' => 2,
                            'impl_name' => '短剧送审成功回调',
                        ]
                    ]
                ]
            ],
            'app_config_item_list' => [],
        ];

        $header = $this->getCommon();
        $url = $this->domain . '/api/industry/v1/solution/set_impl';

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['data']['error_code'] != 0) {
            return ['msg' => '送审回调配置错误：'. ($data['data']['description'] ?? ''), 'data' => []];
        }

        return ['msg' => '', 'data' => []];
    }

    //上线
    public function online($album_id, $version, $type = 2)
    {
        $body = [
            'album_id' => $album_id,
            'operate' => $type
        ];

        if ($type == 2) $body['version'] = $version;

        $header = $this->getCommon();
        $url = $this->domain . '/api/playlet/v2/album/online/';

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        flog($data,'douyin_online');
        if (!$data || $data['err_no'] != 0) return ['msg' => '上线错误：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => ['version' => $data['data']['version']]];
    }


    //格式话字符串
    private function format_str($str, $len): string
    {
        if (empty($str)) return '';
        return mb_strlen($str) >= $len ? $str : mb_substr($str, 0, ($len - 3)) . '...';
    }

    //获取视频播放信息
    public function getPlayInfo($album_id, $episode_id)
    {
        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'album_id' => $album_id,
            'episode_id' => $episode_id
        ];

        $header = $this->getCommon();
        $url = $this->domain . '/api/playlet/v2/video/play_info/';

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '获取播放链接失败：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => $data['data']];
    }

    //短剧授权
    public function shortPlayAuthorize($album_id, array $app_id_list = [])
    {
        $app_id_lists = $app_id_list ?: [];
        if (empty($app_id_list) || !in_array($this->douyinConf['appid'], $app_id_list)) {
            $app_id_lists[] = $this->douyinConf['appid'];
        }

        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'album_id' => $album_id,
            'app_id_list' => $app_id_lists
        ];

        $header = $this->getCommon();
        $url = $this->domain . '/api/playlet/v2/auth/authorize/';

        //dd($body);
        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '短剧授权失败：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => []];
    }

    public function pageBanding($album_id, $episode_id, array $params): array
    {
        $body = [
            'schema_bind_type' => 1,
            'single_schema_bind' => [
                'album_id' => (int)$album_id,
                'episode_id' => (int)$episode_id,
                'path' => 'pages/playvideo/playvideo',
                'params' => [
                    [
                        'key' => 'vid',
                        'value' => (string)$params['video_id']
                    ],
                    [
                        'key' => 'detail',
                        'value' => (string)$params['detail_id']
                    ]
                ]
            ]
        ];

        if (!empty($params['app_id'])) {
            $body['app_id'] = $params['app_id'];
        }

        $header = $this->getCommon();
        $url = $this->domain . '/api/playlet/v2/album/bind/';

        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '页面绑定失败：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => []];
    }

    //剧集详情查询
    public function albumDetailQuery($album_id, $params)
    {
        $version = $params['version'] ?? 1;
        $offset = empty($params['page']) ? 0 : (int)($params['page']-1);
        $limit = $params['limit'] ?? 30;
        $body = [
            'ma_app_id' => $this->douyinConf['appid'],
            'query_type' => 3,
            'detail_query' => [
                'offset' => $offset,
                'limit' => $limit,
                'album_id' => $album_id,
                'version' => $version
            ]
        ];

        $header = $this->getCommon();
        $url = $this->domain . '/api/playlet/v2/album/fetch/';

        $result = Common::curlRequest($url, 'POST', json_encode($body, JSON_UNESCAPED_UNICODE), $header);
        $data = json_decode($result, true);

        if (!$data || $data['err_no'] != 0) return ['msg' => '剧集查询：'. ($data['err_msg'] ?? ''), 'data' => []];

        return ['msg' => '', 'data' => $data['data']];
    }
}